package service

import (
	"bytes"
	"fmt"
	"github.com/goccy/go-json"
	"io/ioutil"
	"log"
	"net/http"
	"strings"
	"time"
)

// 环信配置
type HuanXinConfig struct {
	ClientID     string
	ClientSecret string
	OrgName      string
	AppName      string
	BaseURL      string
	Token        string
	ExpiresAt    time.Time
}

// Token响应
type TokenResponsess struct {
	AccessToken string `json:"access_token"`
	ExpiresIn   int    `json:"expires_in"`
}

// 用户注册请求
type RegisterRequest struct {
	Username string `json:"username"`
	Password string `json:"password"`
	Nickname string `json:"nickname,omitempty"`
}

// 用户登录请求
type LoginRequest struct {
	GrantType      string `json:"grant_type"`
	Username       string `json:"username"`
	AutoCreateUser bool   `json:"autoCreateUser"`
	Ttl            int    `json:"ttl"`
}

// 用户登录响应
type LoginResponse struct {
	AccessToken string    `json:"access_token"`
	ExpiresIn   int       `json:"expires_in"`
	User        *UserInfo `json:"user"`
}

// 用户信息
type UserInfo struct {
	UUID      string `json:"uuid"`
	Username  string `json:"username"`
	Nickname  string `json:"nickname"`
	Activated bool   `json:"activated"`
	Created   int64  `json:"created"`
}

// 环信客户端
type HuanXinClient struct {
	Config *HuanXinConfig
	Client *http.Client
}

type UpdateUserRequest struct {
	Nickname string `json:"nickname,omitempty"`
	Password string `json:"password,omitempty"`
}

// 创建新客户端
func NewHuanXinClient() *HuanXinClient {
	config := &HuanXinConfig{
		ClientID:     "YXA69tvnE3N2Q3aQS1UZWAxHWA",
		ClientSecret: "YXA64_vQjU0fFJxTFPJiaapjWhgF-3w",
		OrgName:      "1150250601209497",
		AppName:      "demo",
		BaseURL:      "https://a1.easemob.com",
	}
	return &HuanXinClient{
		Config: config,
		Client: &http.Client{Timeout: 10 * time.Second},
	}
}

// 发送HTTP请求
func (hx *HuanXinClient) doRequest(method, url string, body interface{}, headers map[string]string) ([]byte, error) {
	var reqBody []byte
	var err error

	if body != nil {
		reqBody, err = json.Marshal(body)
		if err != nil {
			return nil, fmt.Errorf("编码请求体失败: %v", err)
		}
	}

	req, err := http.NewRequest(method, url, bytes.NewBuffer(reqBody))
	if err != nil {
		return nil, fmt.Errorf("创建请求失败: %v", err)
	}

	// 设置请求头
	req.Header.Set("Content-Type", "application/json")
	for k, v := range headers {
		req.Header.Set(k, v)
	}

	resp, err := hx.Client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("请求失败: %v", err)
	}
	defer resp.Body.Close()

	respBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("读取响应体失败: %v", err)
	}

	if resp.StatusCode >= 400 {
		return nil, fmt.Errorf("请求失败, 状态码: %d, 响应: %s", resp.StatusCode, string(respBody))
	}

	return respBody, nil
}

// 获取Token
func (hx *HuanXinClient) GetToken() error {
	url := fmt.Sprintf("%s/%s/%s/token", hx.Config.BaseURL, hx.Config.OrgName, hx.Config.AppName)

	requestBody := map[string]string{
		"grant_type":    "client_credentials",
		"client_id":     hx.Config.ClientID,
		"client_secret": hx.Config.ClientSecret,
	}

	respBody, err := hx.doRequest("POST", url, requestBody, nil)
	if err != nil {
		return fmt.Errorf("获取Token失败: %v", err)
	}

	var tokenResp TokenResponsess
	if err := json.Unmarshal(respBody, &tokenResp); err != nil {
		return fmt.Errorf("解析Token响应失败: %v", err)
	}

	hx.Config.Token = tokenResp.AccessToken
	hx.Config.ExpiresAt = time.Now().Add(time.Duration(tokenResp.ExpiresIn) * time.Second)
	return nil
}

// 检查并刷新Token
func (hx *HuanXinClient) CheckToken() error {
	if hx.Config.Token == "" || time.Now().After(hx.Config.ExpiresAt) {
		return hx.GetToken()
	}
	return nil
}

// 注册用户
func (hx *HuanXinClient) RegisterUser(username, password, nickname string) error {
	if err := hx.CheckToken(); err != nil {
		return fmt.Errorf("Token检查失败: %v", err)
	}

	url := fmt.Sprintf("%s/%s/%s/users", hx.Config.BaseURL, hx.Config.OrgName, hx.Config.AppName)

	user := RegisterRequest{
		Username: username,
		Password: password,
		Nickname: nickname,
	}

	headers := map[string]string{
		"Authorization": "Bearer " + hx.Config.Token,
	}

	_, err := hx.doRequest("POST", url, user, headers)
	if err != nil {
		return fmt.Errorf("注册用户失败: %v", err)
	}

	return nil
}

func (hx *HuanXinClient) UpdateUserAvatar(username, avatarURL string) error {
	// 检查token是否有效
	if err := hx.CheckToken(); err != nil {
		return fmt.Errorf("Token检查失败: %v", err)
	}

	// 构造请求URL
	url := fmt.Sprintf("%s/%s/%s/metadata/user/%s", hx.Config.BaseURL, hx.Config.OrgName, hx.Config.AppName, username)

	// 发送PUT请求更新用户信息
	payload := strings.NewReader("avatarurl=" + avatarURL)

	req, _ := http.NewRequest("PUT", url, payload)

	req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Add("content-type", "application/x-www-form-urlencoded")
	req.Header.Add("Authorization", "Bearer "+hx.Config.Token)
	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)
	fmt.Println(string(body))
	return nil
}

// 用户登录
func (hx *HuanXinClient) UserLogin(username, password string) (*LoginResponse, error) {
	url := fmt.Sprintf("%s/%s/%s/token", hx.Config.BaseURL, hx.Config.OrgName, hx.Config.AppName)

	loginReq := LoginRequest{
		Username:       username,
		GrantType:      "inherit",
		AutoCreateUser: true,
		Ttl:            0,
	}
	//ss["Bearer"] = "\n" + hx.Config.Token
	headers := map[string]string{
		"Authorization": "Bearer " + hx.Config.Token,
	}
	respBody, err := hx.doRequest("POST", url, loginReq, headers)
	if err != nil {
		return nil, fmt.Errorf("用户登录失败: %v", err)
	}

	var loginResp LoginResponse
	if err := json.Unmarshal(respBody, &loginResp); err != nil {
		return nil, fmt.Errorf("解析登录响应失败: %v", err)
	}

	return &loginResp, nil
}

// 获取用户信息
func (hx *HuanXinClient) GetUserInfo(username string) (*UserInfo, error) {
	if err := hx.CheckToken(); err != nil {
		return nil, fmt.Errorf("Token检查失败: %v", err)
	}

	url := fmt.Sprintf("%s/%s/%s/users/%s", hx.Config.BaseURL, hx.Config.OrgName, hx.Config.AppName, username)

	headers := map[string]string{
		"Authorization": "Bearer " + hx.Config.Token,
	}

	respBody, err := hx.doRequest("GET", url, nil, headers)
	if err != nil {
		return nil, fmt.Errorf("获取用户信息失败: %v", err)
	}

	var userInfo UserInfo
	if err := json.Unmarshal(respBody, &userInfo); err != nil {
		return nil, fmt.Errorf("解析用户信息失败: %v", err)
	}

	return &userInfo, nil
}

// 3. 更新用户信息
func (hx *HuanXinClient) UpdateUserInfo(username string, update *UpdateUserRequest) error {
	if err := hx.CheckToken(); err != nil {
		return fmt.Errorf("Token检查失败: %v", err)
	}

	url := fmt.Sprintf("%s/%s/%s/users/%s", hx.Config.BaseURL, hx.Config.OrgName, hx.Config.AppName, username)

	headers := map[string]string{
		"Authorization": "Bearer " + hx.Config.Token,
	}

	_, err := hx.doRequest("PUT", url, update, headers)
	if err != nil {
		return fmt.Errorf("更新用户信息失败: %v", err)
	}

	return nil
}

type MuteRequest struct {
	MuteDuration int64    `json:"mute_duration"`       // 禁言时长(秒)，-1表示永久禁言
	Usernames    []string `json:"usernames,omitempty"` // 可选指定用户，空表示全局禁言
}

// 禁言响应
type MuteResponse struct {
	Data      map[string]bool `json:"data"`
	Duration  int64           `json:"duration"`
	RequestID string          `json:"request_id"`
	Timestamp int64           `json:"timestamp"`
}

// 1. 设置全局禁言
func (hx *HuanXinClient) GlobalMute(duration int64) error {
	if err := hx.CheckToken(); err != nil {
		return fmt.Errorf("Token检查失败: %v", err)
	}

	url := fmt.Sprintf("%s/%s/%s/mutes", hx.Config.BaseURL, hx.Config.OrgName, hx.Config.AppName)

	muteReq := MuteRequest{
		MuteDuration: duration, // -1表示永久禁言，>0表示禁言秒数
	}

	headers := map[string]string{
		"Authorization": "Bearer " + hx.Config.Token,
	}

	_, err := hx.doRequest("POST", url, muteReq, headers)
	if err != nil {
		return fmt.Errorf("设置全局禁言失败: %v", err)
	}

	return nil
}

// 2. 解除全局禁言
func (hx *HuanXinClient) RemoveGlobalMute() error {
	if err := hx.CheckToken(); err != nil {
		return fmt.Errorf("Token检查失败: %v", err)
	}

	url := fmt.Sprintf("%s/%s/%s/mutes", hx.Config.BaseURL, hx.Config.OrgName, hx.Config.AppName)

	headers := map[string]string{
		"Authorization": "Bearer " + hx.Config.Token,
	}

	_, err := hx.doRequest("DELETE", url, nil, headers)
	if err != nil {
		return fmt.Errorf("解除全局禁言失败: %v", err)
	}

	return nil
}

// 3. 获取禁言列表
func (hx *HuanXinClient) GetMuteList() (*MuteResponse, error) {
	if err := hx.CheckToken(); err != nil {
		return nil, fmt.Errorf("Token检查失败: %v", err)
	}

	url := fmt.Sprintf("%s/%s/%s/mutes", hx.Config.BaseURL, hx.Config.OrgName, hx.Config.AppName)

	headers := map[string]string{
		"Authorization": "Bearer " + hx.Config.Token,
	}

	respBody, err := hx.doRequest("GET", url, nil, headers)
	if err != nil {
		return nil, fmt.Errorf("获取禁言列表失败: %v", err)
	}

	var muteResp MuteResponse
	if err := json.Unmarshal(respBody, &muteResp); err != nil {
		return nil, fmt.Errorf("解析禁言列表失败: %v", err)
	}

	return &muteResp, nil
}

// 添加好友
func (hx *HuanXinClient) AddFriend(ownerUsername, friendUsername uint64) (*FriendResponse, error) {
	// 检查token有效性
	if err := hx.CheckToken(); err != nil {
		return nil, fmt.Errorf("token检查失败: %v", err)
	}

	// 构建请求URL
	url := fmt.Sprintf("%s/%s/%s/users/%d/contacts/users/%d",
		hx.Config.BaseURL,
		hx.Config.OrgName,
		hx.Config.AppName,
		ownerUsername,
		friendUsername)

	// 设置请求头
	headers := map[string]string{
		"Authorization": "Bearer " + hx.Config.Token,
		"Content-Type":  "application/json",
	}

	// 发送POST请求(无需请求体)
	_, err := hx.doRequest("POST", url, nil, headers)
	if err != nil {
		return nil, fmt.Errorf("添加好友请求失败: %v", err)
	}

	// 解析响应
	var friendResp FriendResponse

	return &friendResp, nil
}

type ZhuceAll struct {
	Username string `json:"username"`
	Password string `json:"password"`
}

// 批量添加好友
func (hx *HuanXinClient) AddUserAll(zhuceAll []*ZhuceAll) (*FriendResponse, error) {
	// 检查token有效性
	if err := hx.CheckToken(); err != nil {
		return nil, fmt.Errorf("token检查失败: %v", err)
	}

	// 构建请求URL
	url := fmt.Sprintf("%s/%s/%s/users",
		hx.Config.BaseURL,
		hx.Config.OrgName,
		hx.Config.AppName)

	// 设置请求头
	headers := map[string]string{
		"Authorization": "Bearer " + hx.Config.Token,
		"Content-Type":  "application/json",
	}
	// 发送POST请求(无需请求体)
	_, err := hx.doRequest("POST", url, zhuceAll, headers)
	if err != nil {
		return nil, fmt.Errorf("添加好友请求失败: %v", err)
	}
	var friendResp FriendResponse

	return &friendResp, nil
}

// 好友关系响应结构体
type FriendResponse struct {
	Success bool   `json:"success"`
	Error   string `json:"error"`
	// 可以根据环信API实际返回的字段添加更多字段
}

func Test() {
	// 初始化配置 - 请替换为你的实际配置

	// 创建客户端
	hxClient := NewHuanXinClient()

	// 示例1: 注册用户
	username := "testuser1"
	password := "Test@1234"
	nickname := "测试用户"

	err := hxClient.RegisterUser(username, password, nickname)
	if err != nil {
		log.Printf("注册用户失败: %v", err)
	} else {
		log.Println("用户注册成功")
	}

	// 示例2: 用户登录
	loginResp, err := hxClient.UserLogin(username, password)
	if err != nil {
		log.Printf("用户登录失败: %v", err)
	} else {
		log.Printf("用户登录成功, Token: %s, 过期时间: %d秒",
			loginResp.AccessToken, loginResp.ExpiresIn)
		log.Printf("用户信息: %+v", loginResp.User)
	}

	// 示例3: 获取用户信息
	userInfo, err := hxClient.GetUserInfo(username)
	if err != nil {
		log.Printf("获取用户信息失败: %v", err)
	} else {
		log.Printf("用户详细信息: %+v", userInfo)
	}
}
